package com.hopes.bizz.protocol.hj212.bo;

import cn.allbs.hj212.enums.HjDataFlag;
import cn.allbs.hj212.model.*;
import com.hopes.bizz.common.core.util.CRCUtils;
import com.hopes.bizz.common.core.util.CollectionUtils;
import com.hopes.bizz.protocol.hj212.constant.HJ212Constant;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author lyb
 * @version 1.0
 * @date 2023/3/8 9:43
 */
public class HjDataBuild {

    public static HjData mergeHjData(List<HjData> dataList) {
        if (CollectionUtils.isEmpty(dataList)) {
            return null;
        }
        int size = dataList.size();
        if (size == 1) {
            return dataList.get(0);
        }

        //排序
        dataList.sort(Comparator.comparing(HjData::getPNo));

        //合并cp
        List<CpData> cpDataList = new ArrayList<>();
        for (HjData fragmentData : dataList) {
            CpData cp = fragmentData.getCp();
            if (cp != null) {
                cpDataList.add(cp);
            }
        }
        Map<String, Pollution> pollMap = new HashMap<>();
        Map<String, Device> deviceMap = new HashMap<>();
        Map<String, LiveSide> liveSideMap = new HashMap<>();
        cpDataList.stream().forEach(v -> {
            Map<String, Pollution> pollution = v.getPollution();
            Map<String, Device> device = v.getDevice();
            Map<String, LiveSide> liveSide = v.getLiveSide();
            if (pollution != null) {
                pollMap.putAll(pollution);
            }
            if (device != null) {
                deviceMap.putAll(device);
            }
            if (liveSide != null) {
                liveSideMap.putAll(liveSide);
            }
        });

        CpData mergeCp = new CpData();
        mergeCp.setPollution(pollMap);
        mergeCp.setDevice(deviceMap);
        mergeCp.setLiveSide(liveSideMap);

        // 读取最后一个片段
        HjData lastFragmentData = dataList.get(size - 1);
        HjData result = new HjData();
        result.setCn(lastFragmentData.getCn());
        result.setMn(lastFragmentData.getMn());
        result.setQn(lastFragmentData.getQn());
        result.setSt(lastFragmentData.getSt());
        result.setPw(lastFragmentData.getPw());
        // 设置最后一次数据包片段的时间
        String dataTime = lastFragmentData.getCp().getDataTime();
        mergeCp.setDataTime(dataTime);
        result.setCp(mergeCp);
        // 合并后移除分包标识，不处理应答和版本
        List<HjDataFlag> dataFlag = lastFragmentData.getDataFlag();
        dataFlag.remove(HjDataFlag.D);
        result.setDataFlag(dataFlag);
        return result;
    }

    public static String writeHjDataAsString(HjData hjData) {

        if (Objects.isNull(hjData)) {
            return null;
        }

        String qn = hjData.getQn();
        String st = hjData.getSt();
        String cn = hjData.getCn();
        String pw = hjData.getPw();
        String mn = hjData.getMn();

        //包头
        StringBuilder sb = new StringBuilder();
        sb.append("QN=").append(qn).append(";").
                append("ST=").append(st).append(";").
                append("CN=").append(cn).append(";").
                append("PW=").append(pw).append(";").
                append("MN=").append(mn).append(";");
        // flag
        List<HjDataFlag> hjDataFlags = Optional.ofNullable(hjData.getDataFlag()).orElseGet(ArrayList::new);
        Integer sysFlag = hjDataFlags.stream().map(HjDataFlag::getBit).reduce(0, Integer::sum);
        sb.append("Flag=").append(sysFlag).append(";");

        // dataTime
        CpData cp = hjData.getCp();
        String dataTime = cp.getDataTime();
        sb.append("CP=&&DataTime=").append(dataTime).append(";");


        Map<String, Pollution> pollMap = cp.getPollution();
        if (pollMap != null) {
            pollMap.forEach((code, value) -> {
                String flag = value.getFlag();
                if (flag != null) {
                    sb.append(code).append("-Flag=").append(flag).append(",");
                }
                BigDecimal rtd = value.getRtd();
                if (rtd != null) {
                    sb.append(code).append("-Rtd=").append(rtd.doubleValue()).append(",");
                }
                BigDecimal max = value.getMax();
                if (max != null) {
                    sb.append(code).append("-Max=").append(max.doubleValue()).append(",");
                }
                BigDecimal min = value.getMin();
                if (min != null) {
                    sb.append(code).append("-Min=").append(min.doubleValue()).append(",");
                }
                BigDecimal avg = value.getAvg();
                if (avg != null) {
                    sb.append(code).append("-Avg=").append(avg.doubleValue()).append(",");
                }
                BigDecimal cou = value.getCou();
                if (cou != null) {
                    sb.append(code).append("-Cou=").append(cou.doubleValue()).append(",");
                }
                BigDecimal zsAvg = value.getZsAvg();
                if (zsAvg != null) {
                    sb.append(code).append("-ZsAvg=").append(zsAvg.doubleValue()).append(",");
                }
                BigDecimal zsMax = value.getZsMax();
                if (zsMax != null) {
                    sb.append(code).append("-ZsMax=").append(zsMax.doubleValue()).append(",");
                }
                BigDecimal zsMin = value.getZsMin();
                if (zsMin != null) {
                    sb.append(code).append("-ZsMin=").append(zsMin.doubleValue()).append(",");
                }
                BigDecimal zsRtd = value.getZsRtd();
                if (zsRtd != null) {
                    sb.append(code).append("-ZsRtd=").append(zsRtd.doubleValue()).append(",");
                }
                Integer rs = value.getRs();
                if (rs != null) {
                    sb.append(code).append("-RS=").append(rs).append(",");
                }
                BigDecimal rt = value.getRt();
                if (rt != null) {
                    sb.append(code).append("-RT=").append(rt.doubleValue()).append(",");
                }
            });
        }


        //污染治理设施设备状态和时间
        Map<String, Device> deviceMap = cp.getDevice();
        if (deviceMap != null) {
            deviceMap.forEach((code, device) -> {
                int rs = device.getRs();
                sb.append(code).append("-RS=").append(rs).append(",");
                BigDecimal rt = device.getRt();
                if (rt != null) {
                    sb.append(code).append("-RT=").append(rt.doubleValue()).append(",");
                }
            });
        }

        sb.deleteCharAt(sb.lastIndexOf(","));
        sb.append("&&");
        String crc = CRCUtils.getCRC16(sb.toString());
        sb.insert(0, String.format("##%04d", sb.length()));
        sb.append(crc).append(HJ212Constant.SEPARATE);
        return sb.toString();
    }
}
